/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.worlds.object;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import net.worlds.WorldsException;
import net.worlds.Main;
import net.worlds.PropChangeHandler;
import net.worlds.ui.UI;
import org.jbox2d.collision.shapes.PolygonDef;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2D;

/**
 *
 * @author Jacob Morgan
 */
public class Box extends Part{
    private final int[] xVerts = new int[4];
    private final int[] yVerts = new int[4];
    protected Vec2D size;
    public Box() throws WorldsException
    {
        super("Box");
        constructor();
    }
    
    public Box(String type) throws WorldsException
    {
        super(type);
        constructor();
    }

    private void constructor() throws WorldsException
    {
        addPropChangeHandler("Size", new PropChangeHandler()
        {
            @Override
            public void handle(final Object oldValue, final Object value) throws WorldsException {

                try {
                    Vec2D vec = (Vec2D) value;
                    if(vec.x < 0.125 || vec.y < 0.125)
                    {
                        System.err.println("The minimum size of a box is (0.125, 0.125)");
                        Vec2D oldVec = (Vec2D) oldValue;
                        if(oldVec != null && oldVec.x >= 0.125 && oldVec.y >= 0.125)
                            setProp("Size", oldVec, true);
                        else
                            setProp("Size", new Vec2D(0.125f, 0.125f), true);
                    }
                    else
                    {
                        if(vec.x < 3 || vec.y < 3)
                        {
                            if(inWorld)
                                body.setBullet(true);
                            else
                                bd.isBullet = true;
                        }
                        Vec2D oldCentroid = PolygonShape.computeCentroid(((PolygonDef)sd).vertices);
                        ((PolygonDef) sd).setAsBox((float) vec.x / 2, (float) vec.y / 2);
                        Vec2D newCentroid = PolygonShape.computeCentroid(((PolygonDef)sd).vertices);
                        ((PolygonDef)sd).translateLocal(oldCentroid.sub(newCentroid));
                        if(inWorld)
                        {
                            rebuildShape();
                        }
                        size = vec;
                    }
                } catch (WorldsException ex) {
                    Main.error(ex);
                }
            }
        });
        addPropChangeHandler("Platform", new PropChangeHandler()
        {
            @Override
            public void handle(Object oldValue, Object value) throws WorldsException {
                if(inWorld)
                    getBody().resetFiltering();
            }
        });
        sd = new PolygonDef();
        ((PolygonDef)sd).setAsBox(2.5f, 2.5f);
        sd.restitution = 0.4f;
        sd.density = 1;
        sd.friction = 0.8f;
        bd.angularDamping = 0.5f;
        if(Main.getGame().type != 0)
        {
            bd.linearDamping = 1f;
            bd.angularDamping = 1f;
        }
        bd.position = new Vec2D(0, 0);
    }

    @Override
    public void draw(Graphics g) throws WorldsException
    {
        draw(g, 0);
    }

    public void draw(Graphics g, int t) throws WorldsException
    {
        if(defaultStroke == null)
            defaultStroke = ((Graphics2D)g).getStroke();
        if(body == null || shape == null || disabled)
            return;
        Graphics2D g2 = (Graphics2D) g;
        Vec2D worldPos = getDrawPosition();
        Vec2D imgPos = new Vec2D(worldPos.x - size.x * 0.5f, worldPos.y + size.y * 0.5f).worldToScreen(Main.getView());
        Vec2D rotateCenter = worldPos.worldToScreen(Main.getView());
        Vec2D screenSize = size.toScreenUnits();
        int ix = (int) imgPos.x;
        int iy = (int) imgPos.y;
        int ssx = (int) screenSize.x;
        int ssy = (int) screenSize.y;
        AffineTransform original = g2.getTransform();
        double angle = -body.getAngle() - rotationDiff;
        if(angle != 0.0)
        {
            AffineTransform rotate = AffineTransform.getRotateInstance(angle, rotateCenter.x, rotateCenter.y);
                g2.transform(rotate);
        }
        Color color = getColorProp("Color");
        if(texture == null || showSelf)
        {
            if(color != null)
            {
                if(t == 0)
                {
                    if(getProp("Transparency") == null)
                        setProp("Transparency", 0f, false);
                    g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) ((1-getFloatProp("Transparency"))*255)));
                }
                else
                    g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), t));
                g.fillRect(ix, iy, ssx, ssy);
            }
        }
        if(texture != null)
        {
            g2.drawImage(texture, ix, iy, ssx, ssy, null);
        }
        if(selected == true)
            g.setColor(Color.white);
        else if(color != null)
        {
            color = color.darker();
            g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), (int) ((1-getFloatProp("Transparency"))*255)));
        }
        if(color != null && (getBooleanProp("ShowBorder") && (texture == null || showSelf)) || selected)
        {
            if(inUse)
            {
                ((Graphics2D)g).setStroke(dashedStroke);
                g.setColor(Color.black);
                g.drawRect(ix, iy, ssx, ssy);
                ((Graphics2D)g).setStroke(defaultStroke);
            }
            else
                g.drawRect(ix, iy, ssx, ssy);
        }
        if(selected && UI.mouseMode == UI.MODE_SCALE && !(this instanceof Ladder))
        {
            g.setColor(Color.white);
            g.fillRect(ix - 4, iy - 4, 8, 8);
            g.fillRect(ix + ssx - 4, iy - 4, 8, 8);
            g.fillRect(ix - 4, iy + ssy - 4, 8, 8);
            g.fillRect(ix + ssx - 4, iy + ssy - 4, 8, 8);
            g.setColor(Color.black);
            g.drawRect(ix - 4, iy - 4, 8, 8);
            g.drawRect(ix + ssx - 4, iy - 4, 8, 8);
            g.drawRect(ix - 4, iy + ssy - 4, 8, 8);
            g.drawRect(ix + ssx - 4, iy + ssy - 4, 8, 8);
        }
        g2.setTransform(original);
        if(label != null && !isCharacter)
        {
            drawLabel(g, null);
        }
    }
    @Override
    public void drawLabel(Graphics g, Vec2D pos) throws WorldsException
    {
        if(label == null)
            return;
        Vec2D center;
        if(pos == null)
            center = getPosition().worldToScreen(Main.getView());
        else
            center = pos;
        FontMetrics fm = g.getFontMetrics();
        Rectangle2D r = fm.getStringBounds(label, g);
        int textX = (int) (center.x - r.getWidth()/2);
        int textY = (int) (center.y - size.toScreenUnits().y/2 - 10);
        g.setColor(Color.black);
        g.drawString(label, textX + 1, textY + 1);
        g.setColor(Color.white);
        g.drawString(label, textX, textY);
    }
}
